package org.axed.user.client.util;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;

/**
 * Just like a tower, but improves speed for several reverse lookups
 */
public class IdxTower extends Tower {
	/**
	 * reverse list
	 * get quick reverse lookups
	 */
	IntList rlist = new IntList();

	/**
	 * To which point is the revlist valid?
	 */
	int revvalid = 0;
 
	/**
	 * Constructor
	 */
	public IdxTower() {
		super();
		rlist.add(0);
	}

//	public void add(int v) {
//		super.add(v);
//	}

	/**
	 * Clears the tower.
	 */
	public void clear() {
		super.clear();

		rlist.clear();
		rlist.add(0);
		revvalid = 0;
	}

	/**
	 * Returns a debug string.
	 */
	public String debug() {
		String s = super.debug();

		s+= "R: ";
		for(int i = 0; i < rlist.size(); i++) {
			s += rlist.get(i) + " ";
		}

		return s;
	}

  
	public void delete(int start, int end) {
		super.delete(start, end);

		int rv = get(start);
		if (revvalid > rv) {
			revvalid = rv;
		}
	}

//	public int get(int index) {
//		return super.get(index);
//	}

	/**
	 * Inserts a value at index.
	 */
	public void insert(int v, int index) {
		super.insert(v, index);

		int rv = get(index);
		if (revvalid > rv) {
			revvalid = rv;
		}
	}

	public void remove(int index) {
		super.remove(index);

		int rv = get(index);
		if (revvalid > rv) {
			revvalid = rv;
		}
	}

	
//	public int oldReverseGet(int value) {
//		for(int i = 0; i < size(); i++) {
//			if (get(i) >= value) {
//				return i;
//			}
//		}
//		return -1;
//	}


	public int reverseGet(int value) {
		if (revvalid < value) {
			revvalidize(value);
		}
		int r = rlist.get(value);
		return rlist.get(value);
	}

	/**
	 * Sets a value v at index.
	 *
	 * @return false, if nothing has changed
	 */
	public boolean set(int index, int v) {
		if (!super.set(index, v)) {
			return false;
		}

		int rv = get(index);
		if (revvalid > rv) {
			revvalid = rv;
		}
		return true;
	}

//	public int size() {
//		return super.size();
//	}

//privates

	/**
	 * Make the rlist valid until vi
	 */
	private void revvalidize(int vi) {
		//revvalid = 0;
		int c = reverseGet(revvalid);
		int rs = rlist.size();

		for(int v = revvalid + 1; v <= vi; v++) {
			while (get(c) < v) {
				c++;
			}
			if (rs > v) {
				rlist.set(v, c);
			} else {
				rlist.add(c);
			}
		}
		revvalid = vi;
 	}
}
